package com.weifly.egp.service.trade;

import com.weifly.egp.service.config.GridConfigService;
import com.weifly.egp.service.enums.OrderStatusEnum;
import com.weifly.egp.util.HttpRequestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 基于网格魔方的股票交易
 *
 * Created by weijianxin on 2019/1/28.
 */
public class GridStockTradeService extends StockTradeService {

    private Logger logger = LoggerFactory.getLogger(StockTradeService.class);

    // 从配置文件读取地址
    // private static final String API_ADDR = "http://47.97.104.3:11191/api/";

    private static final String QUERY_ADDR = "query?category=2"; //当日委托

    private static final String ORDER_ADDR = "order"; // 委托下单

    //private static final String TEST_QUERY_STR = "委托时间\\u0009申请编号\\u0009证券代码\\u0009证券名称\\u0009买卖标志\\u0009买卖\\u0009委托类型\\u0009委托状态\\u0009委托价格\\u0009委托数量\\u0009成交价格\\u0009成交数量\\u0009成交金额\\u0009已撤数量\\u0009撤单标志\\u0009业务名称\\u0009帐号类别\\u0009股东代码\\u0009资金帐号\\u0009委托编号\\u0009返回信息\\u0009可撤单标志\\u0009参数\\u0009保留信息\\u000a09:46:15\\u0009220\\u0009159915\\u0009创业板\\u00091\\u0009卖出\\u0009买卖\\u0009已成\\u00091.3100\\u00092000.00\\u00091.3100\\u00092000.00\\u00092620.00\\u00090.00\\u0009正常\\u0009担保品卖出\\u00090\\u00090604897632\\u00098009182589\\u0009220\\u0009\\u00091\\u00090,买卖,卖出,已成\\u0009\\u000a09:46:30\\u0009222\\u0009159915\\u0009创业板\\u00091\\u0009卖出\\u0009买卖\\u0009已成\\u00091.3200\\u00092000.00\\u00091.3200\\u00092000.00\\u00092640.00\\u00090.00\\u0009正常\\u0009担保品卖出\\u00090\\u00090604897632\\u00098009182589\\u0009222\\u0009\\u00091\\u00090,买卖,卖出,已成\\u0009\\u000a09:46:45\\u0009226\\u0009159915\\u0009创业板\\u00090\\u0009买入\\u0009买卖\\u0009已报\\u00091.2900\\u00092000.00\\u00090.0000\\u00090.00\\u00090.00\\u00090.00\\u0009正常\\u0009融资买入\\u00090\\u00090604897632\\u00098009182589\\u0009226\\u0009\\u00091\\u00090,买卖,买入,已报\\u0009\\u000a09:47:00\\u0009229\\u0009159915\\u0009创业板\\u00090\\u0009买入\\u0009买卖\\u0009已报\\u00091.2800\\u00092000.00\\u00090.0000\\u00090.00\\u00090.00\\u00090.00\\u0009正常\\u0009融资买入\\u00090\\u00090604897632\\u00098009182589\\u0009229\\u0009\\u00091\\u00090,买卖,买入,已报\\u0009\\u000a09:59:27\\u0009338\\u0009510050\\u000950ETF\\u00090\\u0009买入\\u0009买卖\\u0009已成\\u00092.4700\\u00091000.00\\u00092.4700\\u00091000.00\\u00092470.00\\u00090.00\\u0009正常\\u0009融资买入\\u00091\\u0009E049070369\\u00098009182589\\u0009338\\u0009\\u00091\\u00090,买卖,买入,已成\\u0009\\u000a10:01:15\\u0009362\\u0009300271\\u0009华宇软件\\u00091\\u0009卖出\\u0009买卖\\u0009已撤\\u000914.5000\\u0009200.00\\u00090.0000\\u00090.00\\u00090.00\\u0009200.00\\u0009正常\\u0009担保品卖出\\u00090\\u00090604897632\\u00098009182589\\u0009362\\u0009\\u00091\\u00091,买卖,卖出,已撤\\u0009\\u000a10:35:01\\u0009558\\u0009159915\\u0009创业板\\u00090\\u0009买入\\u0009买卖\\u0009已成\\u00091.3100\\u00092000.00\\u00091.3100\\u00092000.00\\u00092620.00\\u00090.00\\u0009正常\\u0009融资买入\\u00090\\u00090604897632\\u00098009182589\\u0009558\\u0009\\u00091\\u00090,买卖,买入,已成\\u0009\\u000a10:35:14\\u0009559\\u0009159915\\u0009创业板\\u00090\\u0009买入\\u0009买卖\\u0009已报\\u00091.3000\\u00092000.00\\u00090.0000\\u00090.00\\u00090.00\\u00090.00\\u0009正常\\u0009融资买入\\u00090\\u00090604897632\\u00098009182589\\u0009559\\u0009\\u00091\\u00090,买卖,买入,已报\\u0009\\u000a10:35:57\\u0009563\\u0009159915\\u0009创业板\\u00091\\u0009卖出\\u0009买卖\\u0009已报\\u00091.3300\\u00092000.00\\u00090.0000\\u00090.00\\u00090.00\\u00090.00\\u0009正常\\u0009担保品卖出\\u00090\\u00090604897632\\u00098009182589\\u0009563\\u0009\\u00091\\u00090,买卖,卖出,已报\\u0009\\u000a10:43:29\\u0009611\\u0009159915\\u0009创业板\\u00091\\u0009卖出\\u0009买卖\\u0009已报\\u00091.3200\\u00092000.00\\u00090.0000\\u00090.00\\u00090.00\\u00090.00\\u0009正常\\u0009担保品卖出\\u00090\\u00090604897632\\u00098009182589\\u0009611\\u0009\\u00091\\u00090,买卖,卖出,已报\\u0009";
    private static final String TEST_QUERY_STR = "委托时间\\u0009申请编号\\u0009证券代码\\u0009证券名称\\u0009买卖标志\\u0009买卖\\u0009委托类型\\u0009委托状态\\u0009委托价格\\u0009委托数量\\u0009成交价格\\u0009成交数量\\u0009成交金额\\u0009已撤数量\\u0009撤单标志\\u0009业务名称\\u0009帐号类别\\u0009股东代码\\u0009资金帐号\\u0009委托编号\\u0009返回信息\\u0009可撤单标志\\u0009参数\\u0009保留信息\\u000a09:46:15\\u0009220\\u0009159915\\u0009创业板\\u00090\\u0009买入\\u0009买卖\\u0009已报\\u00091.3200\\u00092000.00\\u00090.00\\u00090.00\\u00090.00\\u00090.00\\u0009正常\\u0009融资买入\\u00090\\u00090604897632\\u00098009182589\\u0009220\\u0009\\u00091\\u00090,买卖,卖出,已报\\u0009\\u000a";

    private GridConfigService gridConfigService;

    public void setGridConfigService(GridConfigService gridConfigService) {
        this.gridConfigService = gridConfigService;
    }

    private String createQueryAddr(){
        String apiUrl = this.gridConfigService.getApiUrl();
        if(apiUrl==null || apiUrl.isEmpty()){
            throw new RuntimeException("apiUrl为空！");
        }
        if(apiUrl.endsWith("/")){
            return apiUrl + QUERY_ADDR;
        }else{
            return apiUrl + "/" + QUERY_ADDR;
        }
    }

    private String createOrderAddr(){
        String apiUrl = this.gridConfigService.getApiUrl();
        if(apiUrl==null || apiUrl.isEmpty()){
            throw new RuntimeException("apiUrl为空！");
        }
        if(apiUrl.endsWith("/")){
            return apiUrl + ORDER_ADDR;
        }else{
            return apiUrl + "/" + ORDER_ADDR;
        }
    }

    public List<StockOrderInfo> getOrderList(){
        List<StockOrderInfo> orderList = new ArrayList<>();

        String sendOrderStr =  HttpRequestUtils.sendGet(this.createQueryAddr(), "UTF-8");
        //String sendOrderStr = TEST_QUERY_STR;
        //String sendOrderStr = null;
        if(sendOrderStr==null || sendOrderStr.isEmpty()){
            return orderList;
        }

        String[] sendOrders = sendOrderStr.split("\\\\u000a");
        for(int i=0;i<sendOrders.length;i++){
            String oneOrder = sendOrders[i];
            if(oneOrder==null || oneOrder.trim().isEmpty()){
                continue;
            }
            String[] orderFields = oneOrder.split("\\\\u0009");
            if(orderFields.length<2){
                continue;
            }
            if(orderFields[0].indexOf("委托时间")!=-1){
                continue;
            }
            StockOrderInfo orderInfo = new StockOrderInfo();
            this.setOrderTime(orderInfo, orderFields[0]); // 委托时间
            orderInfo.setOrderNumber(orderFields[1]); // 申请编号
            orderInfo.setStockCode(orderFields[2]); // 证券代码
            orderInfo.setStockName(orderFields[3]); // 证券名称
            this.setBuyOrSell(orderInfo, orderFields[4]); // 买卖标志
            // 5 买卖
            // 6 委托类型
            this.setOrderStatus(orderInfo, orderFields[7]); // 委托状态
            orderInfo.setEntrustPrice(Double.valueOf(orderFields[8])); // 委托价格
            orderInfo.setEntrustSize(Double.valueOf(orderFields[9]).intValue()); // 委托数量
            // 10 成交价格
            // 11 成交数量
            // 12 成交金额
            // 13 已撤数量
            // 14 撤单标志
            // 15 业务名称
            // 16 帐号类别
            // 17 股东代码
            // 18 资金帐号
            // 19 委托编号
            // 20 返回信息
            // 21 可撤单标志
            // 22 参数
            // 23 保留信息
            orderList.add(orderInfo);
        }
        //this.printOrderList(orderList);
        return orderList;
    }

    public StockOrderInfo sendOrder(SendOrderInfo sendOrderInfo){
        Map<String, String> param = new LinkedHashMap<String, String>();
        if(sendOrderInfo.getCategory()==null){
            throw new RuntimeException("委托种类不能为空");
        }
        if(sendOrderInfo.getStockCode()==null){
            throw new RuntimeException("证券代码不能为空");
        }
        if(sendOrderInfo.getEntrustPrice()==null){
            throw new RuntimeException("委托价格不能为空");
        }
        if(sendOrderInfo.getEntrustSize()==null){
            throw new RuntimeException("委托数量不能为空");
        }

        // 委托种类
        param.put("category", String.valueOf(sendOrderInfo.getCategory().getValue()));
        // 报价方式
        param.put("type", "0");
        // 证券代码
        param.put("symbol", sendOrderInfo.getStockCode());
        // 委托价格
        param.put("price", String.valueOf(sendOrderInfo.getEntrustPrice()));
        // 委托数量
        param.put("quantity", String.valueOf(sendOrderInfo.getEntrustSize()));
        String sendOrderResponse =  HttpRequestUtils.sendPost(this.createOrderAddr(), param);

        if(sendOrderResponse==null || sendOrderResponse.trim().isEmpty()){
            logger.info("发送请求后，无返回内容");
            return null;
        }

        // 正常返回："12"
        // 错误返回："[120147][当前时间不允许委托][curr_time=173728]"
        // 错误返回："[120359][该融资融券业务不在允许交易时间范围内][curr_time=190027,curr_date=20181208,init_date=20181210]"
        // 错误返回："[260200][可用资金不足][p_occur_balance=2640.63,p_enable_balance=1918.49]"
        int orderNumber = -1;
        if(!sendOrderResponse.startsWith("\"") || !sendOrderResponse.endsWith("\"")) {
            logger.info("下单失败：" + sendOrderResponse);
            return null;
        }

        String orderNumberStr = sendOrderResponse.substring(1, sendOrderResponse.length()-1);
        try{
            orderNumber = Integer.parseInt(orderNumberStr);
        }catch(NumberFormatException e){
            logger.error("委托单不是数字："+sendOrderResponse, e);
            return null;
        }

        StockOrderInfo orderInfo = new StockOrderInfo();
        orderInfo.setStockCode(sendOrderInfo.getStockCode());
        orderInfo.setStockName(sendOrderInfo.getStockName());
        orderInfo.setOrderNumber(String.valueOf(orderNumber));
        orderInfo.setOrderStatus(OrderStatusEnum.status_5);
        orderInfo.setOrderTime(System.currentTimeMillis());
        orderInfo.setBuyOrSell(sendOrderInfo.getBuyOrSell());
        orderInfo.setEntrustPrice(sendOrderInfo.getEntrustPrice());
        orderInfo.setEntrustSize(sendOrderInfo.getEntrustSize());
        orderInfo.setCreditBuy(sendOrderInfo.isCreditBuy());
        return orderInfo;
    }

    public static void main(String[] args){
        GridStockTradeService s = new GridStockTradeService();
        List<StockOrderInfo> orderList = s.getOrderList();
        System.out.println("委托单数量："+orderList.size());
    }
}
